<?php
declare (strict_types=1);

namespace app\command;

use app\common\Common;
use app\cps\service\DebugLosService;
use app\model\DebugLogs;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use app\model\User;
use app\model\ResponsibilityPerson;
use app\model\Link;
use think\facade\Cache;
use think\facade\Db;
use app\model\Videos;
use app\model\PayRecord;
use app\model\LaunchAccount;

class baiDuRealTimeInvestData extends Command
{
    private $model;
    private $payRecordModel;
    private $userModel;
    private $videosModel;
    private $responsibilityPersonModel;
    private $launchAccountModel;

    protected function configure()
    {
        // 指令配置
        $this->setName('douyinrealtimeinvestdata')
            ->setDescription('the douyinrealtimeinvestdata command');
    }

    protected function initModel()
    {
        $this->model = new Link();
        $this->payRecordModel = new PayRecord();
        $this->userModel = new User();
        $this->videosModel = new Videos();
        $this->responsibilityPersonModel = new ResponsibilityPerson();
        $this->launchAccountModel = new launchAccount();
    }

    /**
     * 命令行的执行。
     * @param Input $input
     * @param Output $output
     * @return int|void|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    protected function execute(Input $input, Output $output)
    {
        // 实例化模型。命令行没法使用注入方式。
        $this->initModel();
        // 执行数据的获取.
        $rs = $this->collectData();
        // 返回结果
        if ($rs) { // 如果有错误。
            $error = $rs['message'] ?? '';
            $debugLogs = new DebugLogs();
            $debugLogsService = new DebugLosService($debugLogs);
            // 数据
            $insert_data = ['link_id' => 0, 'order_id' => 0, 'db_result' => $error, 'debug_scene' => '百度获取投放数据'];
            // 记录下
            $debugLogsService->save($insert_data, 'invest_data_collection');
        }
    }

    /**
     * 获取数据
     * @return array|string[]
     */
    protected function collectData()
    {
        try {
            ini_set('memory_limit', '-1');
            $redis = Cache::store('redis')->handler();
            $redis->select(5);

            $key1 = config('redis_key.baidu_real_time_investment_create_time') . date('Ymd');
            $key2 = config('redis_key.baidu_real_time_investment_link_user_register_num');

            $linkData = $this->model->getDataByWhere(['link_switch' => 1, 'media_id' => 3], 'id, video_id, video_detail_id, advertiser_id, responsibility_person_id, rebate, echo_rate');

            $accessToken = Common::getBaiduAccessToken();

            $hearder['json'] = 1;

            $startDate = date('Y-m-d');
            $endDate = date('Y-m-d');
            $data = $accountIds = $responsibilityPersonIds = [];
            $url = 'https://api.baidu.com/json/feed/v1/ReportFeedService/getRealTimeFeedData';
            $subUserListKey = config('baidu.baidu_sub_user_list');
            $subUserList = $redis->hGetAll($subUserListKey);

            //
            foreach ($linkData as $value) {
                if (empty($value['advertiser_id']) || empty($subUserList[$value['advertiser_id']])) {
                    continue;
                }

                // 获取成本
                $requestData = [
                    'header' => [
                        'userName' => $subUserList[$value['advertiser_id']],
                        'accessToken' => $accessToken
                    ],
                    'body' => [
                        'realTimeRequestType' => [
                            'performanceData' => ['cost'],
                            'startDate' => $startDate,
                            'endDate' => $endDate,
                            'levelOfDetails' => 2,
                            'reportType' => 700,
                            'unitOfTime' => 5
                        ]
                    ]
                ];

                $result = Common::_curl($url, $requestData, 'POST', $hearder);
                $result = json_decode($result, true);

                if ($result['header']['desc'] == 'success' && $result['header']['status'] == 0) {
                    $value['cost'] = 0;
                    if (!empty($result['body']['data'])) {
                        $value['cost'] = round($result['body']['data'][0]['kpis'][0], 2);
                    }

                    $data[] = $value;
                } else {
                    return ['message' => $result['header']['desc'] . '；link_id：' . $value['id']];
                }

                $accountIds[] = $value['advertiser_id'];
                $responsibilityPersonIds[] = $value['responsibility_person_id'];
            }

            $redisUserLinkRegisterData = [];
            if ($data) {
                // 短剧
                $videoIds = array_column($data, 'video_id');
                $videoData = $this->videosModel->getDataByIds($videoIds, 'id, name');
                $videos = array_column($videoData, 'name', 'id');

                $ids = array_column($data, 'id');
                $userWhere = [
                    ['link_id', 'in', $ids],
                    ['activation_time', 'between', [date('Y-m-d') . ' 00:00:00', date('Y-m-d') . ' 23:59:59']]
                ];
                $userInfo = $this->userModel->getBatchDataByWhere($userWhere, 'id, link_id');
                $payData = $this->payRecordModel->getInfo(['link_id' => $ids, 'status' => 1, 'consume_date' => date('Ymd')], 'link_id, uid, total_fee, activation_time');

                $newUids = $newUserPayData = $rechargeNumber = $userData = [];

                if ($userInfo) {

                    foreach ($userInfo as $key => $value) {
                        $newUids[] = $value['id'];
                        $redisUserLinkRegisterData[$value['link_id']][] = $value['id'];
                    }

                    // 当天这个链接上的用户数据
                    $links = array_column($userInfo, 'link_id');
                    $userData = array_count_values($links);
                }

                $newUserNum = [];
                // 当天新用户充值（当期充值）
                $startTime = strtotime(date('Y-m-d'));
                $endTime = strtotime(date('Y-m-d')) + 86400;
                foreach ($payData as $key => $value) {
                    if (strtotime($value['activation_time']) >= $startTime && $endTime > strtotime($value['activation_time'])) {
                        $newUserPayData[$value['link_id']][] = $value['total_fee'];
                        $newUserNum[$value['link_id']][] = $value['uid'];
                    }
                    // $payResult[$value['link_id']][] = $value['total_fee'];
                    $rechargeNumber[$value['link_id']][] = $value['uid'];
                }

                // 获取返点数据
                $launchAccountData = $this->launchAccountModel->getDataByWhere(['account_id' => $accountIds], 'account_id, rebate');
                $launchAccount = array_column($launchAccountData, 'rebate', 'account_id');

                // 获取负责人数据
                $responsibilityPersonData = $this->responsibilityPersonModel->getDataByWhere(['id' => $responsibilityPersonIds], 'id, name');
                $responsibilityPerson = array_column($responsibilityPersonData, 'name', 'id');

                foreach ($data as $key => $item) {
                    $data[$key]['video_name'] = $videos[$item['video_id']];

                    $currentRecharge = empty($newUserPayData[$item['id']]) ? 0 : array_sum($newUserPayData[$item['id']]);
                    $data[$key]['current_recharge'] = round($currentRecharge, 2); // 当期充值

                    // by huangxiaoshan 2023-07-12 当期充值95折扣
                    $tmp_recharge_discount = round(bcmul((string)$currentRecharge, '0.95', 3), 2); // 当期95充值;
                    $data[$key]['current_recharge_discount'] = $tmp_recharge_discount;
                    // end.

                    $data[$key]['current_recovery'] = $item['cost'] == 0 ? 0 : round($currentRecharge / $item['cost'] * 100, 2) . '%'; // 当期回收
                    $conversionNumber = empty($rechargeNumber[$item['id']]) ? 0 : count(array_unique($rechargeNumber[$item['id']])); // 充值人数
                    $data[$key]['conversion_number'] = $conversionNumber;

                    $newRechargeNumber = empty($newUserPayData[$item['id']]) ? 0 : count($newUserPayData[$item['id']]); // 新充笔数
                    $newUserNumber = empty($newUserNum[$item['id']]) ? 0 : count(array_unique($newUserNum[$item['id']])); // 新充人数
                    $data[$key]['new_recharge_number'] = $newRechargeNumber;
                    $data[$key]['new_user_number'] = $newUserNumber;
                    $data[$key]['conversion_cost'] = $newUserNumber == 0 ? 0 : round($item['cost'] / $newUserNumber, 2); // 转化成本

                    $data[$key]['fans_cost'] = !empty($userData[$item['id']]) ? round($item['cost'] / $userData[$item['id']]) : 0; // 粉丝成本
                    // $totalRecharge = empty($payResult[$item['id']]) ? 0 : array_sum($payResult[$item['id']]); // 当天累计充值
                    $data[$key]['total_recharge'] = $currentRecharge;

                    $data[$key]['per_capita_contribution'] = $newUserNumber == 0 ? 0 : round($currentRecharge / $newUserNumber, 2); // 人均贡献

                    $userLinkRegisterNum = empty($redisUserLinkRegisterData[$item['id']]) ? 0 : count($redisUserLinkRegisterData[$item['id']]);
                    // 转化率
                    $redisKey = config('redis_key.link_same_day_click_num') . date('Ymd') . '-' . $item['id'];
                    $redis->set($redisKey, $userLinkRegisterNum); // by update huangxiaoshan 2023-07-13
                    if (empty($newUserNumber) || empty($userLinkRegisterNum)) {
                        $data[$key]['conversion_rate'] = '0%';
                    } else {
                        $data[$key]['conversion_rate'] = round($newUserNumber / $userLinkRegisterNum * 100, 2) . '%';
                    }
                    // by huangxiaoshan 2023-07-13 时间依赖于定时任务。
                    $redis->set($key2 . $item['id'], $userLinkRegisterNum,30*60);
                    // end
                    //$redis->set($key2.$item['id'], $userLinkRegisterNum, 15*60);
                    $data[$key]['media_id'] = 3; // 百度

                    // 实际花费
                    $actualCost = 0;
                    if (!empty($item['rebate'])) {
                        $actualCost = round($item['cost'] / ($item['rebate'] / 100 + 1), 2);
                    } else if (!empty($launchAccount[$item['advertiser_id']])) {
                        $actualCost = round($item['cost'] / ($launchAccount[$item['advertiser_id']] / 100 + 1), 2);
                    }
                    unset($data[$key]['rebate']);
                    // $actualCost = !empty($launchAccount[$item['advertiser_id']]) ? round($item['cost'] / ($launchAccount[$item['advertiser_id']] / 100 + 1), 2) : 0;
                    $data[$key]['actual_recovery'] = $actualCost == 0 ? 0 : round($currentRecharge / $actualCost * 100, 2) . '%'; // 实际回收
                    $data[$key]['actual_cost'] = $tmp_actual_cost = round($actualCost, 2);

                    // by huangxiaoshan 2023-07-12 当期充值95折扣后净利润.
                    $data[$key]['current_recharge_profit'] = bcsub($tmp_recharge_discount, $tmp_actual_cost, 2);
                    // end

                    // 负责人数据
                    $data[$key]['responsibility_person_name'] = $responsibilityPerson[$item['responsibility_person_id']];

                    $data[$key]['revenue'] = round($currentRecharge - $actualCost, 2); // 营收情况

                    // by huangxiaoshan 2023-07-14 新增订单人数
                    $order_count = empty($newUserPayData[$item['id']]) ? 0 : count($newUserPayData[$item['id']]);
                    $data[$key]['order_count'] = $order_count;
                    $data[$key]['avg_person_order'] = 0;
                    if ($order_count && $newUserNumber) {
                        $data[$key]['avg_person_order'] = round(bcdiv((string)$order_count, (string)$newUserNumber,3),2);
                    }
                    // end
                }
            }

            Db::name('real_time_data_cache')->where(['media_id' => 3])->delete(true);
            if ($data) {
                $bool = Db::name('real_time_data_cache')->insertAll($data);
            }

            $redis->set($key1, time(),24*60*60); // 数据产生的时间

            /*$data = Db::name('real_time_data_cache')->where($where)->order('id', 'desc')->select()->toArray();
            foreach ($data as $item) {

                // 获取点击数
                $redisKey = config('redis_key.link_same_day_click_num').date('Ymd').'-'.$item['id'];
                $clickNum = $redis->get($redisKey);
                $totalClickNum = $totalClickNum + $clickNum;

                // 获取当日累计注册用户数
                $linkRegisterUserNum = $redis->get($key2.$item['id']);
                $totalNewUserCount = $totalNewUserCount + $linkRegisterUserNum;
            }

            $result = [
                'create_time' => date('Y-m-d H:i:s'),
                'total_click_num' => $totalClickNum,
                'total_new_user' => $totalNewUserCount,
                'data' => $data
            ];

           */
            return [];

        } catch (\Exception $e) {
            $error = "百度投放账号数据实时采集错误：" . $e->getLine() . "|" . $e->getMessage();
            return ['message' => $error];
        }
    }
}
